package com.blacktech.dbu.auth.entity;

import com.blacktech.dbu.core.annotation.Searchable;
import com.blacktech.dbu.core.common.BaseEntity;
import com.blacktech.dbu.core.dict.UserStatus;
import com.blacktech.dbu.core.dict.UserType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户信息实体
 *
 * @author Yanyunsong
 */
@EqualsAndHashCode(callSuper = true)
@Data
@Entity
@Table(name = "dbu_user")
public class DbuUser extends BaseEntity {

    /**
     * 用户名（唯一标识）
     */
    @Searchable(value = "用户名", priority = 1)
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 50, message = "用户名长度必须在3-50个字符之间")
    @Column(name = "username", unique = true, nullable = false, length = 50)
    private String username;

    /**
     * 密码（BCrypt加密存储）
     */
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, message = "密码长度不能少于6位")
    @Column(name = "password", nullable = false)
    private String password;

    /**
     * 显示名称
     */
    @Searchable(value = "显示名称", priority = 2)
    @NotBlank(message = "显示名称不能为空")
    @Size(max = 100, message = "显示名称不能超过100个字符")
    @Column(name = "display_name", nullable = false, length = 100)
    private String displayName;

    /**
     * 邮箱（可选，用于通知）
     */
    @Searchable(value = "邮箱", priority = 3)
    @Email(message = "邮箱格式不正确")
    @Size(max = 100, message = "邮箱不能超过100个字符")
    @Column(name = "email", length = 100)
    private String email;

    /**
     * 用户类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "user_type", nullable = false, length = 20)
    private UserType userType;

    /**
     * 用户状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private UserStatus status = UserStatus.ENABLED;

    /**
     * 最后登录时间
     */
    @Column(name = "last_login_time")
    private LocalDateTime lastLoginTime;

    /**
     * 登录失败次数
     */
    @Column(name = "login_failed_count")
    private Integer loginFailedCount = 0;

    /**
     * 账户锁定时间
     */
    @Column(name = "locked_time")
    private LocalDateTime lockedTime;

    /**
     * 密码最后修改时间
     */
    @Column(name = "password_changed_time")
    private LocalDateTime passwordChangedTime;

    /**
     * 用户产品权限列表
     */
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    @JsonIgnore
    private List<DbuUserProduct> userProducts = new ArrayList<>();

    /**
     * 操作日志列表
     */
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<DbuOperationLog> operationLogs = new ArrayList<>();

    /**
     * 检查账户是否被锁定
     */
    public boolean isAccountNonLocked() {
        return status != UserStatus.LOCKED;
    }

    /**
     * 检查账户是否启用
     */
    public boolean isEnabled() {
        return status == UserStatus.ENABLED;
    }

    /**
     * 检查是否需要锁定账户（登录失败次数超过5次）
     */
    public boolean shouldBeLocked() {
        return loginFailedCount >= 5;
    }

    /**
     * 检查锁定是否已过期（30分钟）
     */
    public boolean isLockExpired() {
        return lockedTime != null && lockedTime.plusMinutes(30).isBefore(LocalDateTime.now());
    }
}